using System.ComponentModel;

using VSTalk.Engine.Core.Context;
using VSTalk.Engine.Core.EntitySession;
using VSTalk.Engine.Core.EnvironmentManagers.UI;
using VSTalk.Engine.Core.XmppCommunication;
using VSTalk.Engine.Core.XmppCommunication.Services.Authorization;
using VSTalk.Engine.Core.XmppCommunication.Services.ContactManager;
using VSTalk.Engine.Core.XmppUtils;
using VSTalk.Engine.Utils;
using VSTalk.Engine.ViewModel.History;
using VSTalk.Engine.Windows;
using VSTalk.Model;

namespace VSTalk.Engine.ViewModel.ContactList.ClientResources
{
    public class InterlocutorResourceViewModel : IClientResource
    {
        private static IWindowManager WindowManager
        {
            get { return AppServices.Get<IWindowManager>(); }
        }

        public static IModelContext ModelContext
        {
            get { return AppServices.Get<IModelContext>(); }
        }

        private static ISessionModel SessionModel
        {
            get { return AppServices.Get<ISessionModel>(); }
        }

        private readonly Interlocutor _interlocutor;
        private readonly IInterlocutorContext _context;
        private IResourceUpdateHandler _handler;
        private PropertyChangedEventHandler _eventHandler;
        private InterlocutorSummaryViewModel _summary;

        public RelayCommand ShowInterlocutorChat { get; private set; }

        public RelayCommand ShowContactLog { get; private set; }

        public RelayCommand SendRequestAuthorization { get; private set; }

        public RelayCommand RemoveContact { get; private set; }

        public Interlocutor Interlocutor
        {
            get { return _interlocutor; }
        }

        public IInterlocutorContext Context
        {
            get { return _context; }
        }

        public InterlocutorSummaryViewModel Summary
        {
            get { return _summary; }
        }

        public InterlocutorResourceViewModel(Interlocutor interlocutor)
        {
            _interlocutor = interlocutor;
            _summary = new InterlocutorSummaryViewModel(_interlocutor);
            _context = SessionModel.GetInterlocutorContext(interlocutor);
            SetCommands();
        }

        private void SetCommands()
        {
            ShowInterlocutorChat = new RelayCommand(ShowInterlocutorChatExecuted);
            ShowContactLog = new RelayCommand(ShowContactLogExecuted);
            SendRequestAuthorization = new RelayCommand(SendRequestAuthorizationExecuted, SendRequestAuthorizationCanExecute);
            RemoveContact = new RelayCommand(RemoveContactExecuted, RemoveContactCanExecute);
        }

        public void StartListen()
        {
            _eventHandler = (sender, args) =>
            {
                if (_handler != null)
                {
                    _handler.Update();
                }
            };
            _interlocutor.PropertyChanged += _eventHandler;
            _context.PropertyChanged += _eventHandler;
            _summary.StartListen();
        }

        public void StopListen()
        {
            _summary.StopListen();
            _interlocutor.PropertyChanged -= _eventHandler;
            _context.PropertyChanged -= _eventHandler;
        }

        public object Model
        {
            get { return _interlocutor; }
        }

        public void Subscribe(IResourceUpdateHandler handler)
        {
            _handler = handler;
        }


        protected void RemoveContactExecuted()
        {
            var contactManager = CommunicationServiceFactory.Create<ContactManager>(_interlocutor);
            contactManager.RemoveContact(_interlocutor);
        }

        protected bool RemoveContactCanExecute()
        {
            var client = ModelContext.GetClientByContact(_interlocutor);
            if (client == null) return false;
            var context = SessionModel.GetClientContext(client);
            return context.State == ClientState.Connected;
        }

        protected void SendRequestAuthorizationExecuted()
        {
            var authService = CommunicationServiceFactory.Create<AuthorizationProvider>(_interlocutor);
            authService.SendAuthorizationRequest(XmppIdConverter.Jid(_interlocutor));
        }

        protected bool SendRequestAuthorizationCanExecute()
        {
            var client = ModelContext.GetClientByContact(_interlocutor);
            if (client == null) return false;
            var context = SessionModel.GetClientContext(client);
            return !_interlocutor.Subscribed && context.State == ClientState.Connected;
        }

        protected void ShowContactLogExecuted()
        {
            var client = ModelContext.GetClientByContact(_interlocutor);
            var bare = XmppIdConverter.Jid(_interlocutor).Bare;
            var vm = new HistoryExplorerViewModel(client, bare);
            var wnd = new HistoryExplorerWindow();
            wnd.DataContext = vm;
            vm.StartListen();
            wnd.Closed += (sender, args) => vm.StopListen();
            wnd.Show();
        }

        protected void ShowInterlocutorChatExecuted()
        {
            WindowManager.ShowChatWindow(_interlocutor);
        }

    }
}